<template lang="">
  <Component
    ref="refComponent"
    v-bind="{
      ...attrs,
      ...pickOwnForBasicComponent(mappingProps, Component.props, attrs),
    }"
    :class="{
      't-button': true,
      [styles.module]: styles.module,
      'no-wrap-class': mappingProps.noWrap,
    }"
    v-show="mappingProps.visible"
    @Click="onClickHandler"
    :tabIndex="attrs.tabIndex == undefined ? 1 : attrs.tabIndex"
    :title="
      mappingProps.noWrap || mappingProps.showHint
        ? mappingProps.hintMsg ?? mappingProps.label
        : ''
    "
  >
    <!-- <Tooltip v-if="mappingProps.noWrap || mappingProps.showHint">
      {{ hintMsg ?? label }}
    </Tooltip> -->
    <!-- <span :class="{'tbtn-no-wrap':noWrap}"  v-if="!mappingProps.label">{{text}}</span> -->
    <!-- <template
      v-for="slotName in Object.keys(slots)"
      v-if="slotName == 'default'"
      :key="slotName"
      v-slot:[slotName]
    >
      <slot :name="slotName"></slot>
    </template> -->
    <slot name="default"></slot>
    <template v-slot:loading>
      <slot name="default" v-if="slots.hasOwnProperty('loading')"></slot>
      <template v-else>
        <Spinner size="14px" v-if="$q.screen.xs" />
        <SpinnerIos size="14px" color="rgba(0,0,0,0.9)" v-else />
        <span class="block">{{ mappingProps.label }}</span>
      </template>
    </template>
  </Component>
</template>
<script>
import { useQuasar } from '@teld/q-components';
import Component from '@teld/q-components/Button';
import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  fixNameSpace,
  pickOwnForBasicComponent,
} from 't/common/utils';
import {
  defineComponent,
  onBeforeUnmount,
  onMounted,
  ref,
  watch,
  nextTick,
} from 'vue';
import { Spinner, SpinnerIos } from '../spinner';
import Tooltip from '../tooltip';
import styles from './index.module.scss';
import './index.scss';
export * from '@teld/q-components/Button';

export default defineComponent({
  name: 'TButton', //fixNameSpace(Component.name),
  props: {
    ...commonProps,
    ...Component.props,
    showHint: {
      type: Boolean,
      default() {
        return false;
      },
    },
    hintMsg: {
      type: String,
      default() {
        return null;
      },
    },
    enableEvent: {
      type: Boolean,
      default() {
        return false;
      },
    },
    enableEventExpression: {
      type: Boolean,
      default() {
        return true;
      },
    },
    enableEventMessage: {
      type: String,
      default() {
        return '';
      },
    },
    enableComfrimMessage: {
      type: Boolean,
      default() {
        return true;
      },
    },
    comfrimMessage: {
      type: String,
      default() {
        return '';
      },
    },
    shortcutKey: {
      type: String,
      default() {
        return 'none';
      },
    },
    shortcutKeyCombCtrl: {
      type: String,
      default() {
        return null;
      },
    },
    shortcutKeyCombKey: {
      type: String,
      default() {
        return null;
      },
    },
    shortcutKeyCustom: {
      type: String,
      default() {
        return null;
      },
    },
    typeStyle: {
      type: String,
      default() {
        return '';
      },
    },
    ripple: {
      type: [Boolean, Object],
      default() {
        return false;
      },
    },
    loading: {
      type: Boolean,
      default() {
        return false;
      },
    },
  },
  emits: ['click'],
  components: { Component, Tooltip, Spinner, SpinnerIos },
  setup(props, { attrs, emit, expose, slots }) {
    const refComponent = ref();
    const [mappingProps, mappingExpose] = useMappingProps(props, {
      click() {
        refComponent.value.click(...arguments);
      },
      width() {
        return refComponent.value.$el.clientWidth;
      },
    });
    if (mappingProps.typeStyle) {
      mappingProps.color = mappingProps.typeStyle;
    }
    let initDisable = mappingProps.disable;
    let initIcon = mappingProps.icon;
    if (mappingProps.loading) {
      mappingProps.disable = true;
    }
    const $q = useQuasar();

    expose(mappingExpose);

    onMounted(() => {
      window.addEventListener('keydown', handleKeyPress);
    });

    onBeforeUnmount(() => {
      window.removeEventListener('keydown', handleKeyPress);
    });

    async function onClickHandler(params) {
      // 事件触发
      if (
        mappingProps.enableEvent &&
        !mappingProps.enableEventExpression &&
        mappingProps.enableEventMessage != ''
      ) {
        enableEventFunction();
        return;
      }
      // 确认消息
      if (
        mappingProps.enableComfrimMessage &&
        mappingProps.comfrimMessage != ''
      ) {
        let result = await enableComfrimFunction();
        if (!result) {
          return;
        }
      }
      emit('click',params);
    }
    watch(
      () => {
        return mappingProps.typeStyle;
      },
      (newVal, oldVal) => {
        if (newVal) {
          mappingProps.color = mappingProps.typeStyle;
        }
      },
    );
    watch(
      () => {
        return mappingProps.icon;
      },
      (newVal, oldVal) => {
        initIcon = newVal;
      },
    );
    watch(
      () => {
        return mappingProps.loading;
      },
      (newVal, oldVal) => {
        mappingProps.disable = initDisable;
        mappingProps.icon = initIcon;
        if (mappingProps.loading) {
          mappingProps.disable = true;
          mappingProps.icon = initIcon ?? '';
        }
      },
    );
    watch(
      () => {
        return mappingProps.disable;
      },
      (newVal, oldVal) => {
        if (!newVal && oldVal) {
          let current = refComponent.value.$el.tabIndex;
          if (current != attrs.tabIndex) {
            nextTick(() => {
              refComponent.value.$el.setAttribute('tabindex', attrs.tabIndex);
            });
          }
        }
      },
    );

    const enableEventFunction = () => {
      $q.notify({
        closeBtn: true,
        type: 'warning',
        position: 'bottom-right',
        message: mappingProps.enableEventMessage,
      });
    };

    const enableComfrimFunction = () => {
      return new Promise((resolve, reject) => {
        $q.dialog({
          title: '操作确认',
          message: mappingProps.comfrimMessage,
          cancel: true,
          persistent: true,
        })
          .onOk(() => {
            resolve(true);
          })
          .onCancel(() => {
            resolve(false);
          });
      });
    };

    // 监听键盘事件
    const handleKeyPress = event => {
      if (mappingProps.shortcutKey == 'none') {
        return;
      }
      let eventObj = {
        'ctrl': event.ctrlKey,
        'shift': event.shiftKey,
        'alt': event.altKey,
        'ctrl+shift': event.ctrlKey && event.shiftKey,
      };
      switch (mappingProps.shortcutKey) {
        case 'Ctrl+S':
          if (eventObj.ctrl && event.key === 's') {
            event.preventDefault();
            onClickHandler();
          }
          break;
        case 'combined':
          if (
            eventObj[mappingProps.shortcutKeyCombCtrl.toLowerCase()] &&
            event.key.toLowerCase() ===
              mappingProps.shortcutKeyCombKey.toLowerCase()
          ) {
            event.preventDefault();
            onClickHandler();
          }
          break;
        case 'custom':
          //仅支持类型 xxx 或 ctrl/shift/alt + xxx
          let inputString = mappingProps.shortcutKeyCustom;
          let splitArray = inputString.split('+');

          if (
            splitArray.length == 1 &&
            event.key.toLowerCase() ===
              mappingProps.shortcutKeyCustom.toLowerCase()
          ) {
            event.preventDefault();
            onClickHandler();
          }

          if (splitArray.length > 1) {
            if (
              eventObj[splitArray[0].toLowerCase()] &&
              event.key.toLowerCase() === splitArray[1].toLowerCase()
            ) {
              event.preventDefault();
              onClickHandler();
            }
          }
          break;
      }
    };

    return {
      refComponent,
      attrs,
      pickOwnForBasicComponent,
      mappingProps,
      Component,
      styles,
      onClickHandler,
      slots,
    };
  },
});
</script>
<style lang="scss">
.no-wrap-class {
  span.block {
    overflow: hidden;
    text-overflow: ellipsis;
  }
}
</style>
